﻿using System;
using System.Collections.Generic;
using System.Text;

namespace MLForgeSharp.Models.ProbabilisticModels.Bayes
{
    using System;
    using System.Collections.Generic;


    public class NaiveBayesModel
    {
        private Dictionary<int, double> classProbabilities; // 类别先验概率
        private Dictionary<int, Dictionary<int, double>> featureProbabilities; // 特征条件概率

        public NaiveBayesModel()
        {
            classProbabilities = new Dictionary<int, double>();
            featureProbabilities = new Dictionary<int, Dictionary<int, double>>();
        }

        // 训练模型
        public void Train(List<int[]> X, int[] y)
        {
            int totalSamples = y.Length;
            int numFeatures = X[0].Length;

            // 计算类别先验概率
            Dictionary<int, int> classCounts = new Dictionary<int, int>();
            for (int i = 0; i < y.Length; i++)
            {
                if (classCounts.ContainsKey(y[i]))
                {
                    classCounts[y[i]]++;
                }
                else
                {
                    classCounts[y[i]] = 1;
                }
            }

            foreach (int cls in classCounts.Keys)
            {
                classProbabilities[cls] = (double)classCounts[cls] / totalSamples;
            }

            // 计算特征条件概率
            foreach (int cls in classCounts.Keys)
            {
                featureProbabilities[cls] = new Dictionary<int, double>();

                // 获取当前类别的样本
                List<int[]> classSamples = new List<int[]>();
                for (int i = 0; i < y.Length; i++)
                {
                    if (y[i] == cls)
                    {
                        classSamples.Add(X[i]);
                    }
                }

                // 计算每个特征的条件概率
                for (int featureIndex = 0; featureIndex < numFeatures; featureIndex++)
                {
                    Dictionary<int, int> valueCounts = new Dictionary<int, int>();

                    // 统计当前特征值的频率
                    foreach (int[] sample in classSamples)
                    {
                        int value = sample[featureIndex];
                        if (valueCounts.ContainsKey(value))
                        {
                            valueCounts[value]++;
                        }
                        else
                        {
                            valueCounts[value] = 1;
                        }
                    }

                    // 计算条件概率
                    foreach (int value in valueCounts.Keys)
                    {
                        int key = featureIndex * 1000 + value;
                        featureProbabilities[cls][key] = (double)valueCounts[value] / classSamples.Count;
                    }
                }
            }
        }

        // 预测类别
        public int Predict(int[] sample)
        {
            Dictionary<int, double> scores = new Dictionary<int, double>();

            foreach (int cls in classProbabilities.Keys)
            {
                double score = Math.Log(classProbabilities[cls]); // 使用对数避免数值下溢

                for (int featureIndex = 0; featureIndex < sample.Length; featureIndex++)
                {
                    int key = featureIndex * 1000 + sample[featureIndex];
                    if (featureProbabilities[cls].ContainsKey(key))
                    {
                        score += Math.Log(featureProbabilities[cls][key]);
                    }
                    else
                    {
                        score += Math.Log(1e-10); // 平滑处理，避免零概率
                    }
                }

                scores[cls] = score;
            }

            // 找到概率最大的类别
            int predictedClass = -1;
            double maxScore = double.MinValue;
            foreach (KeyValuePair<int, double> kvp in scores)
            {
                if (kvp.Value > maxScore)
                {
                    maxScore = kvp.Value;
                    predictedClass = kvp.Key;
                }
            }

            return predictedClass;
        }
    }


    public class NaiveBayesModelExample
    {
        public NaiveBayesModelExample()
        {
            // 训练数据
            List<int[]> X = new List<int[]>
        {
            new int[] { 1, 0 }, // 样本1
            new int[] { 1, 1 }, // 样本2
            new int[] { 0, 0 }, // 样本3
            new int[] { 0, 1 },  // 样本4
            new int[] { 2, 2 },  // 样本5
            new int[] { 2, 1 }   // 样本6
        };

            int[] y = { 0, 0, 1, 1, 2, 2 }; // 类别标签 (3 个类别)

            // 创建朴素贝叶斯分类器
            NaiveBayesModel classifier = new NaiveBayesModel();
            classifier.Train(X, y);

            // 测试样本
            int[] testSample = { 1, 0 };

            // 预测类别
            int predictedClass = classifier.Predict(testSample);
            Console.WriteLine("Classified as: " + predictedClass);
        }
    }

}
